package com.icim.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

public class TimeUtil {
	private static String strMySQLTimeFormat = "yyyy-MM-dd HH:mm:ss";

	public static String stackTraceToString(Exception excp) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw, true);
		excp.printStackTrace(pw);
		pw.flush();
		sw.flush();
		return sw.toString();
	}

	public static String getEvtTime() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String evt_timestamp = tempDate.format(now.getTime());
		return evt_timestamp;
	}

	public static Timestamp getCurrentTimestamp() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String evt_timestamp = tempDate.format(now.getTime());
		Timestamp timestatmp = null;
		try {
			timestatmp = Timestamp.valueOf(evt_timestamp);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return timestatmp;
	}

	public static String getEvtTimeforVer() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyyMMdd");
		String evt_timestamp = tempDate.format(now.getTime());
		return evt_timestamp;
	}

	public static String getRvTime() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyyMMddHHmmss");
		String evt_timestamp = tempDate.format(now.getTime());
		return evt_timestamp;
	}

	public static String getMillTimeStr() {
		Calendar now = Calendar.getInstance();
		// SimpleDateFormat tempDate = new
		// SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
		SimpleDateFormat tempDate = new SimpleDateFormat(strMySQLTimeFormat);
		String evt_timestamp = tempDate.format(now.getTime());
		return evt_timestamp;
	}
	
	public static String getSixTimeBehindSecond()
	{
		//精确到毫秒，后三位补0
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		Date date = new Date();
		return sdf.format(date)+"000";
	}

	public static Date getMillTime() {// TODO Need format
		return String2Date(getMillTimeStr());
	}

	public static String formatEvtTime(Calendar calendar) {
		SimpleDateFormat tempDate = new SimpleDateFormat(strMySQLTimeFormat);
		String evt_timestamp = tempDate.format(calendar.getTime());
		return evt_timestamp;
	}

	public static String formatRvTime(Calendar calendar) {
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyyMMddHHmmss");
		String evt_timestamp = tempDate.format(calendar.getTime());
		return evt_timestamp;
	}

	public static Date String2Date(String dateString) {
		Date date = new Date();

		try {
			SimpleDateFormat sdf = new SimpleDateFormat(strMySQLTimeFormat);
			date = sdf.parse(dateString);
		} catch (ParseException e) {
			System.out.println(e.getMessage());
		}
		return date;
	}

	public static Date String2Time(String timeString) {
		Date date = null;
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("HH.mm.ss");
			date = sdf.parse(timeString);
		} catch (ParseException e) {
			System.out.println(e.getMessage());
		}
		return date;
	}

	public static Timestamp String2Timestamp(String timeString) {
	    if(StringUtils.isEmpty(timeString)){
	        return null;
	    }
		Timestamp timestatmp = null;
		try {
			timestatmp = Timestamp.valueOf(timeString);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return timestatmp;
	}

	/**
	 * Get time diff value (By min)
	 * 
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static long getDiffMin(String startTime, String endTime) {
		long diff;
		long diffMin = 0;
		long nm = 1000 * 60;// 一分钟的毫秒数
		SimpleDateFormat sd = new SimpleDateFormat(strMySQLTimeFormat);
		try {
			// 获得两个时间的毫秒时间差异
			diff = sd.parse(endTime).getTime() - sd.parse(startTime).getTime();
			diffMin = diff / nm;// 计算差多少分钟
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return diffMin;
	}

	/**
	 * Get time diff value (By min)
	 * 
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static long getDiffMin(Timestamp startTime, Timestamp endTime) {
		long diffMin = 0;
		long nm = 1000 * 60;// 一分钟的毫秒数

		long diff = endTime.getTime() - startTime.getTime();
		diffMin = diff / nm;// 计算差多少分钟 //TODO Double

		return diffMin;
	}

	public static boolean isSpaceCheck(String str) {
		if (null == str || str.length() <= 0 || ("").equals(str)) {
			return true;
		}
		return false;
	}

	/*****
	 * 获取 double类型时间 逻辑混乱，不建议深入研究
	 * ******/
	public static Double getDoubleTime() {
		long now = System.currentTimeMillis(); // 微秒级当前时间
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(now);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		int day = c.get(Calendar.DATE);
		// int year = 2013;
		// int month = 10;
		// int day = 27;
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		int millisecond = c.get(Calendar.MILLISECOND);
		// System.out.println("当前微秒级时间:"+System.currentTimeMillis());
		// System.out.println("当前时间: " + c.get(Calendar.YEAR) + "年 "
		// + (c.get(Calendar.MONTH) + 1) + "月 " + c.get(Calendar.DATE)
		// + "日  周" + (c.get(Calendar.DAY_OF_WEEK) - 1) + "  "
		// + c.get(Calendar.HOUR) + "时 " + c.get(Calendar.MINUTE) + "分 "
		// + c.get(Calendar.SECOND) + "秒 " + c.get(Calendar.MILLISECOND)
		// + " 微秒");
		Double days = Double.valueOf("0");// 统计天数
		for (int i = 1900; i < year; i++) {
			days += getDaysByYear(i);
		}
		// System.out.println("passDays :" + days + "\n");
		int[] days_each_month = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30,
				31, 30, 31 };
		if (isLeepYear(year)) {
			days_each_month[1] = 29;
		}

		for (int i = 0; i < month - 1; i++) {
			days += days_each_month[i];
		}

		days = days + day + 1;
		// 获取微秒
		// long nanoTime = System.nanoTime();
		// String snonoTime = nanoTime+"";
		// String sMicroSecond = snonoTime.substring(snonoTime.length()-6,
		// snonoTime.length()-3);

		double seconds = hour * 3600 + minute * 60 + second;
		double millSeconds = millisecond + seconds * 1000;// 000
															// +Double.valueOf(sMicroSecond);

		Double d = Double.valueOf(millSeconds / (3600 * 24 * 1000) + "");
		return Double.valueOf(days + d);
	}
	
	public static Double getDoubleTimeByTimestamp(Timestamp timestamp) {
		long time = timestamp.getTime(); // 微秒级当前时间
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(time);
		int year = c.get(Calendar.YEAR);
		int month = c.get(Calendar.MONTH) + 1;
		int day = c.get(Calendar.DATE);
		int hour = c.get(Calendar.HOUR_OF_DAY);
		int minute = c.get(Calendar.MINUTE);
		int second = c.get(Calendar.SECOND);
		int millisecond = c.get(Calendar.MILLISECOND);
		Double days = Double.valueOf("0");
		for (int i = 1900; i < year; i++) {
			days += getDaysByYear(i);
		}
		int[] days_each_month = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30,
				31, 30, 31 };
		if (isLeepYear(year)) {
			days_each_month[1] = 29;
		}

		for (int i = 0; i < month - 1; i++) {
			days += days_each_month[i];
		}

		days = days + day + 1;

		double seconds = hour * 3600 + minute * 60 + second;
		double millSeconds = millisecond + seconds * 1000;

		Double d = Double.valueOf(millSeconds / (3600 * 24 * 1000) + "");
		return Double.valueOf(days + d);
	}

	// 获得某年的天数
	private static int getDaysByYear(int year) {
		if (isLeepYear(year)) {
			return 366;
		} else {
			return 365;
		}
	}

	// 判断是否是闰年
	private static boolean isLeepYear(int year) {
		return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
	}

	public static String comInt2String(int value, int length) {
		// System.out.println("value:" + value);
		// System.out.println("length:" + length);
		String s = String.valueOf(value);
		if (s.length() > length) {
			throw new RuntimeException("length is too short.");
		} else if (s.length() == length) {
			return s;
		} else {
			char[] cc = new char[length];
			int i = 0;
			for (; i < length - s.length(); i++) {
				cc[i] = '0';
			}
			for (int j=0; j < s.length();i++,j++) {
				// System.out.println(i);
				cc[i] = s.charAt(j);
			}
			return new String(cc);
		}
	}

	
	/***
	 * 功能描述:将double类型的时间转换为 正常的时间格式如: 2013-08-16 13:04:12 。精确度：精确到秒。
	 * 此函数逻辑混乱,最好不要深入研究
	 * ***/
	public static String getTimestampByDblTime(double dTime) {

		int alldays = (int) dTime, year = 0, mon = 0, day = 0, hour, minute, second, milliSecond,passDays = 0;
		double allFloatPartDay = dTime - alldays;// double时间的小数部分

		StringBuffer timeStamp = new StringBuffer();
		timeStamp.setLength(0);
		// get year
		year = (int) (dTime / 365.25 + 1900);

		// get mon 
		for (int i = 1900; i < year; i++) {
			passDays += getDaysByYear(i);
		}
		int[] days_each_month = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (isLeepYear(year)) {
			days_each_month[1] = 29;
		}
		//get day
		int days = 0;
		int remainDays = alldays - passDays - 1;
		for (int i = 0; i < 12; i++) {
			if ((days + days_each_month[i]) >= remainDays) {
				mon = i + 1;
				day = remainDays - days;
				break;
			}
			days += days_each_month[i];
		}
		// get hour,minute,second
		hour = (int) (24 * allFloatPartDay);
		minute = (int) (24 * 60 * allFloatPartDay - 60 * (hour));
		second = (int) (24 * 60 * 60 * (allFloatPartDay) - 60 * minute - 60 * 60 * hour);
		milliSecond = (int) (24 * 60 * 60 * 1000 * (allFloatPartDay) - 60 * 1000 * minute  - 60 * 60 * 1000 * hour - second * 1000);
		

		timeStamp.append(year).append("-").append(comInt2String(checkTimeMaxVal(mon, "MON"), 2))
				.append("-").append(comInt2String(checkTimeMaxVal(day, "DAY"), 2)).append(" ")
				.append(comInt2String(checkTimeMaxVal(hour, "HOUR"), 2)).append(":")
				.append(comInt2String(checkTimeMaxVal(minute, "MINUTE"), 2)).append(":")
				.append(comInt2String(checkTimeMaxVal(second, "SECOND"), 2));
		return timeStamp.toString();
	}

	public static String getMilliTimestampByDblTime(double dTime) {

        int alldays = (int) dTime, year = 0, mon = 0, day = 0, hour, minute, second, milliSecond,passDays = 0;
        double allFloatPartDay = dTime - alldays;// double时间的小数部分

        StringBuffer timeStamp = new StringBuffer();
        timeStamp.setLength(0);
        // get year
        year = (int) (dTime / 365.25 + 1900);

        // get mon 
        for (int i = 1900; i < year; i++) {
            passDays += getDaysByYear(i);
        }
        int[] days_each_month = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
        if (isLeepYear(year)) {
            days_each_month[1] = 29;
        }
        //get day
        int days = 0;
        int remainDays = alldays - passDays - 1;
        for (int i = 0; i < 12; i++) {
            if ((days + days_each_month[i]) >= remainDays) {
                mon = i + 1;
                day = remainDays - days;
                break;
            }
            days += days_each_month[i];
        }
        // get hour,minute,second
        hour = (int) (24 * allFloatPartDay);
        minute = (int) (24 * 60 * allFloatPartDay - 60 * (hour));
        second = (int) (24 * 60 * 60 * (allFloatPartDay) - 60 * minute - 60 * 60 * hour);
        milliSecond = (int) (24 * 60 * 60 * 1000 * (allFloatPartDay) - 60 * 1000 * minute  - 60 * 60 * 1000 * hour - second * 1000);
        

        timeStamp.append(year).append("-").append(comInt2String(checkTimeMaxVal(mon, "MON"), 2))
                .append("-").append(comInt2String(checkTimeMaxVal(day, "DAY"), 2)).append(" ")
                .append(comInt2String(checkTimeMaxVal(hour, "HOUR"), 2)).append(":")
                .append(comInt2String(checkTimeMaxVal(minute, "MINUTE"), 2)).append(":")
                .append(comInt2String(checkTimeMaxVal(second, "SECOND"), 2))
                .append(comInt2String(milliSecond,3));
        return timeStamp.toString();
    }
	
	
	
	public static int checkTimeMaxVal(int time, String type) {
		if (("MON").equals(type) && time > 12) {
			return 0;
		}
		if (("DAY").equals(type) && time > 31) {
			return 0;
		}
		if (("HOUR").equals(type) || ("MINUTE").equals(type)
				|| ("SECOND").equals(type)) {
			if (time >= 60) {
				return 0;
			}
		}
		return time;
	}
	
	/**
	 * Get Date diff value (By day)
	 * 
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static long getDiffDay(String startTime, String endTime) {
		long diffDays = 0;
		Calendar c1 = Calendar.getInstance();
        c1.clear();
        Calendar c2 = Calendar.getInstance();
        c2.clear();
		Date start_Time = String2Date(startTime); 
		Date end_Time = String2Date(endTime);

        // Set the date for both of the calendar instance
        c1.setTime(start_Time);
        c2.setTime(end_Time);

        // Get the represented date in milliseconds
        long time1 = c1.getTimeInMillis();
        long time2 = c2.getTimeInMillis();

        // Calculate difference in milliseconds
        long diff = time2 - time1;

        // Difference in days
        diffDays = diff / (24 * 60 * 60 * 1000);

		return diffDays;
	}
	
	/**
	 * Get getDateTime yyyy-MM-dd
	 * 
	 * @return
	 */
	public static String getDateTime(String DateTime) {
		Date dateTime = String2Date(DateTime); 
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd");
		String evt_timestamp = tempDate.format(dateTime);
		return evt_timestamp;
	}
	public static String getYesterData() {//获取当前日期的前一天日期
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
		Date dBefore = calendar.getTime();   //得到前一天的时间
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd");
		String evt_timestamp = tempDate.format(dBefore);
		return evt_timestamp;
	}
	public static String getDataAfter(String DateTime ,Integer x) {//获取当前日期的后6个月日期
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.add(Calendar.MONTH, +x);  //设置为后几个月日期
		Date dBefore = calendar.getTime();   //得到后几个月的时间
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd");
		String evt_timestamp = tempDate.format(dBefore);
		return evt_timestamp;
	}
	public static String getCurTime() {//获取当前日期的08整时间
		Calendar dateTime = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd 08:00:00");
		String evt_timestamp = tempDate.format(dateTime.getTime());
		return evt_timestamp;
	}
	
	public static String getYesterTime() {//获取当前日期的前一天的08整时间
//		Date dNow = new Date();   //当前时间
//		Date dBefore = new Date();
		Calendar calendar = Calendar.getInstance(); //得到日历
//		calendar.setTime(dNow);//把当前时间赋给日历
		calendar.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
		Date dBefore = calendar.getTime();   //得到前一天的时间
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd 08:00:00");
		String evt_timestamp = tempDate.format(dBefore);
		return evt_timestamp;
	}
	
	public static String getBefore4Time(String timestamp) {//获取当前时间往前推4小时的时间点
		Date dNow = String2Date(timestamp);
		Calendar calendar = Calendar.getInstance(); //得到日历
		calendar.setTime(dNow);//把当前时间赋给日历
		calendar.add(Calendar.HOUR_OF_DAY, -4);  //设置为当前时间前推4小时
		Date dBefore = calendar.getTime();   //得到前推4小时的时间
		SimpleDateFormat tempDate = new SimpleDateFormat(strMySQLTimeFormat);
		String evt_timestamp = tempDate.format(dBefore);
		return evt_timestamp;
	}
	
	public static String getThickFormat(Double thickness){//将小数0.6转换为0060的格式
		String S = thickness + "";
		String[] s1 = S.split("\\.");//以小数点分隔
		if(s1[0].length() == 1){
			s1[0] = "0" + s1[0];
		}
		if(s1[1].length() == 1){
			s1[1] = s1[1] + "0";
		}else{
			s1[1] = s1[1].substring(0,2);
		}
		return s1[0] + s1[1];
	}
	
	public static String getShiftType(){//根据系统时间，判断白夜班
		Calendar dateTime = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String cur_timestamp = tempDate.format(dateTime.getTime());
		SimpleDateFormat temp_8 = new SimpleDateFormat("yyyy-MM-dd 08:00:00");
		String timestamp_8 = temp_8.format(dateTime.getTime());
		SimpleDateFormat temp_20 = new SimpleDateFormat("yyyy-MM-dd 20:00:00");
		String timestamp_20 = temp_20.format(dateTime.getTime());
		try {
			Date curTime = String2Date(cur_timestamp);
			Date cur_8_time = String2Date(timestamp_8);
			Date cur_20_time = String2Date(timestamp_20);
			if (curTime.getTime() >= cur_8_time.getTime() && 
				curTime.getTime() < cur_20_time.getTime()) {
				return "F";
			} else if (curTime.getTime() < cur_8_time.getTime() ||
					   curTime.getTime() >= cur_20_time.getTime()) {
				return "R";
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return "F";
	}
	
	public static String getLotData() {
		Calendar dateTime = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String cur_timestamp = tempDate.format(dateTime.getTime());
		SimpleDateFormat temp_0 = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
		String timestamp_0 = temp_0.format(dateTime.getTime());
		SimpleDateFormat temp_8 = new SimpleDateFormat("yyyy-MM-dd 08:00:00");
		String timestamp_8 = temp_8.format(dateTime.getTime());
		try {
			Date evtTime = String2Date(cur_timestamp);
			Date evt_0_time = String2Date(timestamp_0);
			Date evt_8_time = String2Date(timestamp_8);
			if (evtTime.getTime() >= evt_0_time.getTime() && 
				evtTime.getTime() < evt_8_time.getTime()) {
				dateTime.add(Calendar.DAY_OF_MONTH, -1);  //设置为前一天
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		Date dBefore = dateTime.getTime();   //得到日期
		SimpleDateFormat evtDate = new SimpleDateFormat("yyyyMMdd");
		String evt_data = evtDate.format(dBefore);
		return evt_data;
	}
	
	public static Timestamp getCurrentTimestampToMilli() {
		Calendar now = Calendar.getInstance();
		SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
		String evt_timestamp = tempDate.format(now.getTime());
		Timestamp timestatmp = null;
		try {
			timestatmp = Timestamp.valueOf(evt_timestamp);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return timestatmp;
	}
	
	

    /****
     * 测试main函数,获取double类型时间，后再转换成String 时间
     * ***/
    public static void main(String[] args) {
        double dTime = getDoubleTime();
        System.out.println("" + getDoubleTime() + "\n");
        // getTimestampByDblTime(41574.10797572048);
        System.out.println( getTimestampByDblTime(dTime));
        System.out.println(getMilliTimestampByDblTime(dTime));
        
        System.out.println(getDoubleTimeByTimestamp(getCurrentTimestamp()));
    }

	
}
